2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-11 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #ifndef __JUCER_TABBEDCOMPONENTHANDLER_JUCEHEADER__
27 #define __JUCER_TABBEDCOMPONENTHANDLER_JUCEHEADER__
30 //==============================================================================
33 class TabbedComponentHandler
: public ComponentTypeHandler
36 //==============================================================================
37 TabbedComponentHandler()
38 : ComponentTypeHandler ("Tabbed Component", "TabbedComponent", typeid (TabbedComponent
), 200, 150)
41 //==============================================================================
42 Component
* createNewComponent (JucerDocument
*)
44 TabbedComponent
* const t
= new TabbedComponent (TabbedButtonBar::TabsAtTop
);
45 t
->setName ("new tabbed component");
47 for (int i
= 3; --i
>= 0;)
53 XmlElement
* createXmlFor (Component
* comp
, const ComponentLayout
* layout
)
55 TabbedComponent
* const t
= dynamic_cast <TabbedComponent
*> (comp
);
56 XmlElement
* const e
= ComponentTypeHandler::createXmlFor (comp
, layout
);
58 if (t
->getOrientation() == TabbedButtonBar::TabsAtTop
)
59 e
->setAttribute ("orientation", "top");
60 else if (t
->getOrientation() == TabbedButtonBar::TabsAtBottom
)
61 e
->setAttribute ("orientation", "bottom");
62 else if (t
->getOrientation() == TabbedButtonBar::TabsAtLeft
)
63 e
->setAttribute ("orientation", "left");
64 else if (t
->getOrientation() == TabbedButtonBar::TabsAtRight
)
65 e
->setAttribute ("orientation", "right");
67 e
->setAttribute ("tabBarDepth", t
->getTabBarDepth());
68 e
->setAttribute ("initialTab", t
->getCurrentTabIndex());
70 for (int i
= 0; i
< t
->getNumTabs(); ++i
)
71 e
->addChildElement (getTabState (t
, i
));
76 bool restoreFromXml (const XmlElement
& xml
, Component
* comp
, const ComponentLayout
* layout
)
78 if (! ComponentTypeHandler::restoreFromXml (xml
, comp
, layout
))
81 TabbedComponent
* const t
= dynamic_cast <TabbedComponent
*> (comp
);
83 if (xml
.getStringAttribute ("orientation") == "top")
84 t
->setOrientation (TabbedButtonBar::TabsAtTop
);
85 else if (xml
.getStringAttribute ("orientation") == "bottom")
86 t
->setOrientation (TabbedButtonBar::TabsAtBottom
);
87 else if (xml
.getStringAttribute ("orientation") == "left")
88 t
->setOrientation (TabbedButtonBar::TabsAtLeft
);
89 else if (xml
.getStringAttribute ("orientation") == "right")
90 t
->setOrientation (TabbedButtonBar::TabsAtRight
);
92 TabbedComponent
defaultTabComp (TabbedButtonBar::TabsAtTop
);
94 t
->setTabBarDepth (xml
.getIntAttribute ("tabBarDepth", defaultTabComp
.getTabBarDepth()));
98 forEachXmlChildElement (xml
, e
)
101 restoreTabState (t
, t
->getNumTabs() - 1, *e
);
104 t
->setCurrentTabIndex (xml
.getIntAttribute ("initialTab", 0));
109 void getEditableProperties (Component
* component
, JucerDocument
& document
, Array
<PropertyComponent
*>& properties
)
111 ComponentTypeHandler::getEditableProperties (component
, document
, properties
);
113 TabbedComponent
* const t
= dynamic_cast <TabbedComponent
*> (component
);
115 properties
.add (new TabOrientationProperty (t
, document
));
116 properties
.add (new TabDepthProperty (t
, document
));
118 if (t
->getNumTabs() > 0)
119 properties
.add (new TabInitialTabProperty (t
, document
));
121 properties
.add (new TabAddTabProperty (t
, document
));
123 if (t
->getNumTabs() > 0)
124 properties
.add (new TabRemoveTabProperty (t
, document
));
127 void addPropertiesToPropertyPanel (Component
* comp
,
128 JucerDocument
& document
,
129 PropertyPanel
& panel
)
131 ComponentTypeHandler::addPropertiesToPropertyPanel (comp
, document
, panel
);
133 TabbedComponent
* const t
= dynamic_cast <TabbedComponent
*> (comp
);
135 for (int i
= 0; i
< t
->getNumTabs(); ++i
)
137 Array
<PropertyComponent
*> properties
;
139 properties
.add (new TabNameProperty (t
, document
, i
));
140 properties
.add (new TabColourProperty (t
, document
, i
));
142 properties
.add (new TabContentTypeProperty (t
, document
, i
));
144 if (isTabUsingJucerComp (t
, i
))
145 properties
.add (new TabJucerFileProperty (t
, document
, i
));
147 properties
.add (new TabContentClassProperty (t
, document
, i
));
149 properties
.add (new TabContentConstructorParamsProperty (t
, document
, i
));
151 properties
.add (new TabMoveProperty (t
, document
, i
, t
->getNumTabs()));
153 panel
.addSection ("Tab " + String (i
), properties
);
157 const String
getCreationParameters (Component
* comp
)
159 TabbedComponent
* const t
= dynamic_cast <TabbedComponent
*> (comp
);
161 switch (t
->getOrientation())
163 case TabbedButtonBar::TabsAtTop
:
164 return "TabbedButtonBar::TabsAtTop";
165 case TabbedButtonBar::TabsAtBottom
:
166 return "TabbedButtonBar::TabsAtBottom";
167 case TabbedButtonBar::TabsAtLeft
:
168 return "TabbedButtonBar::TabsAtLeft";
169 case TabbedButtonBar::TabsAtRight
:
170 return "TabbedButtonBar::TabsAtRight";
176 return String::empty
;
179 void fillInCreationCode (GeneratedCode
& code
, Component
* component
, const String
& memberVariableName
)
181 TabbedComponent
* const t
= dynamic_cast <TabbedComponent
*> (component
);
183 ComponentTypeHandler::fillInCreationCode (code
, component
, memberVariableName
);
186 << memberVariableName
<< "->setTabBarDepth (" << t
->getTabBarDepth() << ");\n";
188 for (int i
= 0; i
< t
->getNumTabs(); ++i
)
190 String contentClassName
;
192 if (isTabUsingJucerComp (t
, i
))
195 = ObjectTypes::loadDocumentFromFile (code
.document
->getFile()
196 .getSiblingFile (getTabJucerFile (t
, i
)), false);
200 code
.includeFilesCPP
.add (getTabJucerFile (t
, i
).replace (".cpp", ".h"));
202 contentClassName
= doc
->getClassName();
208 contentClassName
= getTabClassName (t
, i
);
212 << memberVariableName
214 << quotedString (t
->getTabNames() [i
])
216 << colourToCode (t
->getTabBackgroundColour (i
));
218 if (contentClassName
.isNotEmpty())
220 code
.constructorCode
<< ", new " << contentClassName
;
222 if (getTabConstructorParams (t
, i
).trim().isNotEmpty())
223 code
.constructorCode
<< " ";
225 code
.constructorCode
<< "(" << getTabConstructorParams (t
, i
).trim() << "), true);\n";
229 code
.constructorCode
<< ", 0, false);\n";
234 << memberVariableName
<< "->setCurrentTabIndex (" << t
->getCurrentTabIndex() << ");\n";
236 code
.constructorCode
<< "\n";
239 //==============================================================================
240 static void addNewTab (TabbedComponent
* tc
, const int insertIndex
= -1)
242 tc
->addTab ("Tab " + String (tc
->getNumTabs()), Colours::lightgrey
,
243 new TabDemoContentComp(), true, insertIndex
);
246 //==============================================================================
247 static XmlElement
* getTabState (TabbedComponent
* tc
, int tabIndex
)
249 XmlElement
* xml
= new XmlElement ("TAB");
250 xml
->setAttribute ("name", tc
->getTabNames() [tabIndex
]);
251 setColourXml (*xml
, "colour", tc
->getTabBackgroundColour (tabIndex
));
253 TabDemoContentComp
* const tdc
= dynamic_cast <TabDemoContentComp
*> (tc
->getTabContentComponent (tabIndex
));
258 xml
->setAttribute ("useJucerComp", tdc
->isUsingJucerComp
);
259 xml
->setAttribute ("contentClassName", tdc
->contentClassName
);
260 xml
->setAttribute ("constructorParams", tdc
->constructorParams
);
261 xml
->setAttribute ("jucerComponentFile", tdc
->jucerComponentFile
);
267 static void restoreTabState (TabbedComponent
* tc
, int tabIndex
, const XmlElement
& xml
)
269 tc
->setTabName (tabIndex
, xml
.getStringAttribute ("name", "Tab"));
270 tc
->setTabBackgroundColour (tabIndex
, getColourXml (xml
, "colour", Colours::lightgrey
));
272 TabDemoContentComp
* const tdc
= dynamic_cast <TabDemoContentComp
*> (tc
->getTabContentComponent (tabIndex
));
277 tdc
->isUsingJucerComp
= xml
.getBoolAttribute ("useJucerComp", false);
278 tdc
->contentClassName
= xml
.getStringAttribute ("contentClassName");
279 tdc
->constructorParams
= xml
.getStringAttribute ("constructorParams");
280 tdc
->jucerComponentFile
= xml
.getStringAttribute ("jucerComponentFile");
282 tdc
->updateContent();
286 //==============================================================================
287 static bool isTabUsingJucerComp (TabbedComponent
* tc
, int tabIndex
)
289 TabDemoContentComp
* const tdc
= dynamic_cast <TabDemoContentComp
*> (tc
->getTabContentComponent (tabIndex
));
292 return tdc
!= 0 && tdc
->isUsingJucerComp
;
295 static void setTabUsingJucerComp (TabbedComponent
* tc
, int tabIndex
, const bool b
)
297 TabDemoContentComp
* const tdc
= dynamic_cast <TabDemoContentComp
*> (tc
->getTabContentComponent (tabIndex
));
302 tdc
->isUsingJucerComp
= b
;
303 tdc
->updateContent();
307 static const String
getTabClassName (TabbedComponent
* tc
, int tabIndex
)
309 TabDemoContentComp
* const tdc
= dynamic_cast <TabDemoContentComp
*> (tc
->getTabContentComponent (tabIndex
));
312 return tdc
!= 0 ? tdc
->contentClassName
: String::empty
;
315 static void setTabClassName (TabbedComponent
* tc
, int tabIndex
, const String
& newName
)
317 TabDemoContentComp
* const tdc
= dynamic_cast <TabDemoContentComp
*> (tc
->getTabContentComponent (tabIndex
));
322 tdc
->contentClassName
= newName
;
323 tdc
->updateContent();
327 static const String
getTabConstructorParams (TabbedComponent
* tc
, int tabIndex
)
329 TabDemoContentComp
* const tdc
= dynamic_cast <TabDemoContentComp
*> (tc
->getTabContentComponent (tabIndex
));
332 return tdc
!= 0 ? tdc
->constructorParams
: String::empty
;
335 static void setTabConstructorParams (TabbedComponent
* tc
, int tabIndex
, const String
& newParams
)
337 TabDemoContentComp
* const tdc
= dynamic_cast <TabDemoContentComp
*> (tc
->getTabContentComponent (tabIndex
));
342 tdc
->constructorParams
= newParams
;
343 tdc
->updateContent();
347 static const String
getTabJucerFile (TabbedComponent
* tc
, int tabIndex
)
349 TabDemoContentComp
* const tdc
= dynamic_cast <TabDemoContentComp
*> (tc
->getTabContentComponent (tabIndex
));
352 return tdc
!= 0 ? tdc
->jucerComponentFile
: String::empty
;
355 static void setTabJucerFile (TabbedComponent
* tc
, int tabIndex
, const String
& newFile
)
357 TabDemoContentComp
* const tdc
= dynamic_cast <TabDemoContentComp
*> (tc
->getTabContentComponent (tabIndex
));
362 tdc
->jucerComponentFile
= newFile
;
363 tdc
->updateContent();
368 //==============================================================================
369 class TabDemoContentComp
: public Component
373 : isUsingJucerComp (false)
375 setSize (2048, 2048);
378 ~TabDemoContentComp()
383 void paint (Graphics
& g
)
385 if (getNumChildComponents() == 0)
387 g
.fillCheckerBoard (getLocalBounds(), 50, 50,
388 Colour::greyLevel (0.9f
).withAlpha (0.4f
),
389 Colour::greyLevel (0.8f
).withAlpha (0.4f
));
395 Component
* const c
= getChildComponent (0);
399 c
->setBounds (0, 0, getWidth(), getHeight());
400 setOpaque (c
->isOpaque());
406 if (isUsingJucerComp
)
408 TestComponent
* jucerComp
= dynamic_cast <TestComponent
*> (getChildComponent (0));
411 || jucerComp
->getOwnerDocument() == 0
412 || jucerComp
->getFilename() != jucerComponentFile
)
416 TestComponent
* tc
= new TestComponent (ComponentTypeHandler::findParentDocument (this), 0, false);
417 tc
->setFilename (jucerComponentFile
);
418 tc
->setToInitialSize();
420 addAndMakeVisible (tc
);
431 void parentHierarchyChanged()
436 bool isUsingJucerComp
;
437 String contentClassName
, constructorParams
;
438 String jucerComponentFile
;
441 //==============================================================================
442 class TabOrientationProperty
: public ComponentChoiceProperty
<TabbedComponent
>
445 TabOrientationProperty (TabbedComponent
* comp
, JucerDocument
& document
)
446 : ComponentChoiceProperty
<TabbedComponent
> ("tab position", comp
, document
)
448 choices
.add ("Tabs at top");
449 choices
.add ("Tabs at bottom");
450 choices
.add ("Tabs at left");
451 choices
.add ("Tabs at right");
454 void setIndex (int newIndex
)
456 const TabbedButtonBar::Orientation orientations
[] = { TabbedButtonBar::TabsAtTop
,
457 TabbedButtonBar::TabsAtBottom
,
458 TabbedButtonBar::TabsAtLeft
,
459 TabbedButtonBar::TabsAtRight
};
461 document
.perform (new TabOrienationChangeAction (component
, *document
.getComponentLayout(), orientations
[newIndex
]),
462 "Change TabComponent orientation");
467 switch (component
->getOrientation())
469 case TabbedButtonBar::TabsAtTop
:
471 case TabbedButtonBar::TabsAtBottom
:
473 case TabbedButtonBar::TabsAtLeft
:
475 case TabbedButtonBar::TabsAtRight
:
486 class TabOrienationChangeAction
: public ComponentUndoableAction
<TabbedComponent
>
489 TabOrienationChangeAction (TabbedComponent
* const comp
, ComponentLayout
& layout
, const TabbedButtonBar::Orientation newState_
)
490 : ComponentUndoableAction
<TabbedComponent
> (comp
, layout
),
493 oldState
= comp
->getOrientation();
499 getComponent()->setOrientation (newState
);
507 getComponent()->setOrientation (oldState
);
512 TabbedButtonBar::Orientation newState
, oldState
;
516 //==============================================================================
517 class TabInitialTabProperty
: public ComponentChoiceProperty
<TabbedComponent
>
520 TabInitialTabProperty (TabbedComponent
* comp
, JucerDocument
& document
)
521 : ComponentChoiceProperty
<TabbedComponent
> ("initial tab", comp
, document
)
523 for (int i
= 0; i
< comp
->getNumTabs(); ++i
)
524 choices
.add ("Tab " + String (i
) + ": \"" + comp
->getTabNames() [i
] + "\"");
527 void setIndex (int newIndex
)
529 document
.perform (new InitialTabChangeAction (component
, *document
.getComponentLayout(), newIndex
),
530 "Change initial tab");
535 return component
->getCurrentTabIndex();
539 class InitialTabChangeAction
: public ComponentUndoableAction
<TabbedComponent
>
542 InitialTabChangeAction (TabbedComponent
* const comp
, ComponentLayout
& layout
, const int newValue_
)
543 : ComponentUndoableAction
<TabbedComponent
> (comp
, layout
),
546 oldValue
= comp
->getCurrentTabIndex();
552 getComponent()->setCurrentTabIndex (newValue
);
560 getComponent()->setCurrentTabIndex (oldValue
);
566 int newValue
, oldValue
;
570 //==============================================================================
571 class TabDepthProperty
: public SliderPropertyComponent
,
572 public ChangeListener
575 TabDepthProperty (TabbedComponent
* comp
, JucerDocument
& document_
)
576 : SliderPropertyComponent ("tab depth", 10.0, 80.0, 1.0, 1.0),
580 document
.addChangeListener (this);
585 document
.removeChangeListener (this);
588 void setValue (double newValue
)
590 document
.getUndoManager().undoCurrentTransactionOnly();
592 document
.perform (new TabDepthChangeAction (component
, *document
.getComponentLayout(), roundToInt (newValue
)),
593 "Change TabComponent tab depth");
596 double getValue() const
598 return component
->getTabBarDepth();
601 void changeListenerCallback (ChangeBroadcaster
*)
606 TabbedComponent
* const component
;
607 JucerDocument
& document
;
610 class TabDepthChangeAction
: public ComponentUndoableAction
<TabbedComponent
>
613 TabDepthChangeAction (TabbedComponent
* const comp
, ComponentLayout
& layout
, const int newState_
)
614 : ComponentUndoableAction
<TabbedComponent
> (comp
, layout
),
617 oldState
= comp
->getTabBarDepth();
623 getComponent()->setTabBarDepth (newState
);
631 getComponent()->setTabBarDepth (oldState
);
636 int newState
, oldState
;
640 //==============================================================================
641 class TabAddTabProperty
: public ButtonPropertyComponent
644 TabAddTabProperty (TabbedComponent
* comp
, JucerDocument
& document_
)
645 : ButtonPropertyComponent ("add tab", false),
653 document
.perform (new AddTabAction (component
, *document
.getComponentLayout()),
657 const String
getButtonText() const
659 return "Create a new tab";
662 TabbedComponent
* const component
;
663 JucerDocument
& document
;
666 class AddTabAction
: public ComponentUndoableAction
<TabbedComponent
>
669 AddTabAction (TabbedComponent
* const comp
, ComponentLayout
& layout
)
670 : ComponentUndoableAction
<TabbedComponent
> (comp
, layout
)
677 addNewTab (getComponent());
678 layout
.getDocument()->refreshAllPropertyComps();
686 getComponent()->removeTab (getComponent()->getNumTabs() - 1);
687 layout
.getDocument()->refreshAllPropertyComps();
694 //==============================================================================
695 class TabRemoveTabProperty
: public ButtonPropertyComponent
698 TabRemoveTabProperty (TabbedComponent
* comp
, JucerDocument
& document_
)
699 : ButtonPropertyComponent ("remove tab", true),
707 const StringArray
names (component
->getTabNames());
710 for (int i
= 0; i
< component
->getNumTabs(); ++i
)
711 m
.addItem (i
+ 1, "Delete tab " + String (i
)
712 + ": \"" + names
[i
] + "\"");
714 const int r
= m
.showAt (this);
718 document
.perform (new RemoveTabAction (component
, *document
.getComponentLayout(), r
- 1),
723 const String
getButtonText() const
725 return "Delete a tab...";
728 TabbedComponent
* const component
;
729 JucerDocument
& document
;
732 class RemoveTabAction
: public ComponentUndoableAction
<TabbedComponent
>
735 RemoveTabAction (TabbedComponent
* const comp
, ComponentLayout
& layout
, int indexToRemove_
)
736 : ComponentUndoableAction
<TabbedComponent
> (comp
, layout
),
737 indexToRemove (indexToRemove_
),
740 previousState
= getTabState (comp
, indexToRemove
);
745 delete previousState
;
752 getComponent()->removeTab (indexToRemove
);
753 layout
.getDocument()->refreshAllPropertyComps();
761 addNewTab (getComponent(), indexToRemove
);
762 restoreTabState (getComponent(), indexToRemove
, *previousState
);
763 layout
.getDocument()->refreshAllPropertyComps();
770 XmlElement
* previousState
;
774 //==============================================================================
775 class TabNameProperty
: public ComponentTextProperty
<TabbedComponent
>
778 TabNameProperty (TabbedComponent
* comp
, JucerDocument
& document
, const int tabIndex_
)
779 : ComponentTextProperty
<TabbedComponent
> ("name", 200, false, comp
, document
),
784 void setText (const String
& newText
)
786 document
.perform (new TabNameChangeAction (component
, *document
.getComponentLayout(), tabIndex
, newText
),
790 const String
getText() const
792 return component
->getTabNames() [tabIndex
];
798 class TabNameChangeAction
: public ComponentUndoableAction
<TabbedComponent
>
801 TabNameChangeAction (TabbedComponent
* const comp
, ComponentLayout
& layout
, const int tabIndex_
, const String
& newValue_
)
802 : ComponentUndoableAction
<TabbedComponent
> (comp
, layout
),
803 tabIndex (tabIndex_
),
806 oldValue
= comp
->getTabNames() [tabIndex
];
812 getComponent()->setTabName (tabIndex
, newValue
);
820 getComponent()->setTabName (tabIndex
, oldValue
);
827 String newValue
, oldValue
;
831 //==============================================================================
832 class TabColourProperty
: public ColourPropertyComponent
,
833 private ChangeListener
836 TabColourProperty (TabbedComponent
* comp
, JucerDocument
& document_
, const int tabIndex_
)
837 : ColourPropertyComponent ("colour", false),
839 document (document_
),
842 document
.addChangeListener (this);
847 document
.removeChangeListener (this);
850 void setColour (const Colour
& newColour
)
852 document
.getUndoManager().undoCurrentTransactionOnly();
854 document
.perform (new TabColourChangeAction (component
, *document
.getComponentLayout(), tabIndex
, newColour
),
855 "Change tab colour");
858 const Colour
getColour() const
860 return component
->getTabBackgroundColour (tabIndex
);
863 void resetToDefault()
865 jassertfalse
// shouldn't get called
868 void changeListenerCallback (ChangeBroadcaster
*) { refresh(); }
871 TabbedComponent
* component
;
872 JucerDocument
& document
;
875 class TabColourChangeAction
: public ComponentUndoableAction
<TabbedComponent
>
878 TabColourChangeAction (TabbedComponent
* const comp
, ComponentLayout
& layout
, const int tabIndex_
, const Colour
& newValue_
)
879 : ComponentUndoableAction
<TabbedComponent
> (comp
, layout
),
880 tabIndex (tabIndex_
),
883 oldValue
= comp
->getTabBackgroundColour (tabIndex
);
889 getComponent()->setTabBackgroundColour (tabIndex
, newValue
);
897 getComponent()->setTabBackgroundColour (tabIndex
, oldValue
);
904 Colour newValue
, oldValue
;
908 //==============================================================================
909 class TabContentTypeProperty
: public ComponentChoiceProperty
<TabbedComponent
>
912 TabContentTypeProperty (TabbedComponent
* comp
, JucerDocument
& document
, const int tabIndex_
)
913 : ComponentChoiceProperty
<TabbedComponent
> ("content type", comp
, document
),
916 choices
.add ("Jucer content component");
917 choices
.add ("Named content component");
920 void setIndex (int newIndex
)
922 document
.perform (new TabContentTypeChangeAction (component
, *document
.getComponentLayout(), tabIndex
, newIndex
== 0),
923 "Change tab content type");
928 return isTabUsingJucerComp (component
, tabIndex
) ? 0 : 1;
934 class TabContentTypeChangeAction
: public ComponentUndoableAction
<TabbedComponent
>
937 TabContentTypeChangeAction (TabbedComponent
* const comp
, ComponentLayout
& layout
, const int tabIndex_
, const bool newValue_
)
938 : ComponentUndoableAction
<TabbedComponent
> (comp
, layout
),
939 tabIndex (tabIndex_
),
942 oldValue
= isTabUsingJucerComp (comp
, tabIndex
);
948 setTabUsingJucerComp (getComponent(), tabIndex
, newValue
);
949 layout
.getDocument()->refreshAllPropertyComps();
957 setTabUsingJucerComp (getComponent(), tabIndex
, oldValue
);
958 layout
.getDocument()->refreshAllPropertyComps();
965 bool newValue
, oldValue
;
969 //==============================================================================
970 class TabJucerFileProperty
: public FilePropertyComponent
,
971 public ChangeListener
974 TabJucerFileProperty (TabbedComponent
* const component_
, JucerDocument
& document_
, const int tabIndex_
)
975 : FilePropertyComponent ("jucer file", false, true),
976 component (component_
),
977 document (document_
),
980 document
.addChangeListener (this);
983 ~TabJucerFileProperty()
985 document
.removeChangeListener (this);
988 //==============================================================================
989 void setFile (const File
& newFile
)
991 document
.perform (new JucerCompFileChangeAction (component
, *document
.getComponentLayout(), tabIndex
,
992 newFile
.getRelativePathFrom (document
.getFile().getParentDirectory())
993 .replaceCharacter ('\\', '/')),
994 "Change tab component file");
997 const File
getFile() const
999 return document
.getFile().getSiblingFile (getTabJucerFile (component
, tabIndex
));
1002 void changeListenerCallback (ChangeBroadcaster
*) { refresh(); }
1005 TabbedComponent
* const component
;
1006 JucerDocument
& document
;
1009 class JucerCompFileChangeAction
: public ComponentUndoableAction
<TabbedComponent
>
1012 JucerCompFileChangeAction (TabbedComponent
* const comp
, ComponentLayout
& layout
, const int tabIndex_
, const String
& newState_
)
1013 : ComponentUndoableAction
<TabbedComponent
> (comp
, layout
),
1014 tabIndex (tabIndex_
),
1015 newState (newState_
)
1017 oldState
= getTabJucerFile (comp
, tabIndex
);
1023 setTabJucerFile (getComponent(), tabIndex
, newState
);
1031 setTabJucerFile (getComponent(), tabIndex
, oldState
);
1037 String newState
, oldState
;
1041 //==============================================================================
1042 class TabContentClassProperty
: public ComponentTextProperty
<TabbedComponent
>
1045 TabContentClassProperty (TabbedComponent
* comp
, JucerDocument
& document
, const int tabIndex_
)
1046 : ComponentTextProperty
<TabbedComponent
> ("content class", 256, false, comp
, document
),
1047 tabIndex (tabIndex_
)
1051 void setText (const String
& newText
)
1053 document
.perform (new TabClassNameChangeAction (component
, *document
.getComponentLayout(), tabIndex
, newText
),
1054 "Change TabbedComponent content class");
1057 const String
getText() const
1059 return getTabClassName (component
, tabIndex
);
1065 class TabClassNameChangeAction
: public ComponentUndoableAction
<TabbedComponent
>
1068 TabClassNameChangeAction (TabbedComponent
* const comp
, ComponentLayout
& layout
, const int tabIndex_
, const String
& newValue_
)
1069 : ComponentUndoableAction
<TabbedComponent
> (comp
, layout
),
1070 tabIndex (tabIndex_
),
1071 newValue (newValue_
)
1073 oldValue
= getTabClassName (comp
, tabIndex
);
1079 setTabClassName (getComponent(), tabIndex
, newValue
);
1081 layout
.getDocument()->refreshAllPropertyComps();
1088 setTabClassName (getComponent(), tabIndex
, oldValue
);
1090 layout
.getDocument()->refreshAllPropertyComps();
1095 String newValue
, oldValue
;
1099 //==============================================================================
1100 class TabContentConstructorParamsProperty
: public ComponentTextProperty
<TabbedComponent
>
1103 TabContentConstructorParamsProperty (TabbedComponent
* comp
, JucerDocument
& document
, const int tabIndex_
)
1104 : ComponentTextProperty
<TabbedComponent
> ("constructor params", 512, false, comp
, document
),
1105 tabIndex (tabIndex_
)
1109 void setText (const String
& newText
)
1111 document
.perform (new TabConstructorParamChangeAction (component
, *document
.getComponentLayout(), tabIndex
, newText
),
1112 "Change TabbedComponent content constructor param");
1115 const String
getText() const
1117 return getTabConstructorParams (component
, tabIndex
);
1123 class TabConstructorParamChangeAction
: public ComponentUndoableAction
<TabbedComponent
>
1126 TabConstructorParamChangeAction (TabbedComponent
* const comp
, ComponentLayout
& layout
, const int tabIndex_
, const String
& newValue_
)
1127 : ComponentUndoableAction
<TabbedComponent
> (comp
, layout
),
1128 tabIndex (tabIndex_
),
1129 newValue (newValue_
)
1131 oldValue
= getTabConstructorParams (comp
, tabIndex
);
1137 setTabConstructorParams (getComponent(), tabIndex
, newValue
);
1139 layout
.getDocument()->refreshAllPropertyComps();
1146 setTabConstructorParams (getComponent(), tabIndex
, oldValue
);
1148 layout
.getDocument()->refreshAllPropertyComps();
1153 String newValue
, oldValue
;
1157 //==============================================================================
1158 class TabMoveProperty
: public ButtonPropertyComponent
1161 TabMoveProperty (TabbedComponent
* comp
, JucerDocument
& document_
,
1162 const int tabIndex_
, const int totalNumTabs_
)
1163 : ButtonPropertyComponent ("move tab", false),
1165 document (document_
),
1166 tabIndex (tabIndex_
),
1167 totalNumTabs (totalNumTabs_
)
1172 void buttonClicked()
1175 m
.addItem (1, "Move this tab up", tabIndex
> 0);
1176 m
.addItem (2, "Move this tab down", tabIndex
< totalNumTabs
- 1);
1178 const int r
= m
.showAt (this);
1182 document
.perform (new MoveTabAction (component
, *document
.getComponentLayout(), tabIndex
, tabIndex
+ (r
== 2 ? 1 : -1)),
1187 const String
getButtonText() const
1189 return "Move this tab...";
1192 TabbedComponent
* const component
;
1193 JucerDocument
& document
;
1194 const int tabIndex
, totalNumTabs
;
1197 class MoveTabAction
: public ComponentUndoableAction
<TabbedComponent
>
1200 MoveTabAction (TabbedComponent
* const comp
, ComponentLayout
& layout
,
1201 const int oldIndex_
, const int newIndex_
)
1202 : ComponentUndoableAction
<TabbedComponent
> (comp
, layout
),
1203 oldIndex (oldIndex_
),
1204 newIndex (newIndex_
)
1208 void move (int from
, int to
)
1212 XmlElement
* const state
= getTabState (getComponent(), from
);
1214 getComponent()->removeTab (from
);
1215 addNewTab (getComponent(), to
);
1217 restoreTabState (getComponent(), to
, *state
);
1220 layout
.getDocument()->refreshAllPropertyComps();
1226 move (oldIndex
, newIndex
);
1232 move (newIndex
, oldIndex
);
1237 const int oldIndex
, newIndex
;
1243 #endif // __JUCER_TABBEDCOMPONENTHANDLER_JUCEHEADER__